--- OpenWrt Lua MVC 框架核心应用入口
-- @module core.App
-- @license MIT
-- @author YourName
-- @version 1.0.0


local cjson = require("cjson")
local Router = require("tianku.core.Router")
local Controller = require("tianku.core.Controller")
local config = require("tianku.config")

local _M = {}

-- 初始化应用
function _M:new()
    local instance = {
        router = Router:new(),
        controllers = {},
        middlewares = {},
        config = config
    }
    return setmetatable(instance, self)
end

--- 加载路由配置
-- @param route_file string 路由配置文件路径
function _M:load_routes(route_file)
     local routes = require(route_file or "tianku.config.route")
    
    -- 支持ThinkPHP风格路由注册
    for _, route in ipairs(routes) do
        if type(route) == "function" then
            route(self.router)  -- 支持路由闭包注册
        else
            self:_register_route(route)
        end
    end
end

--- 注册单条路由（私有方法）
function _M:_register_route(route)
    local methods = route.methods or { route.method }
    local handler = route.handler
    
    -- 支持中间件链
    if route.middleware then
        handler = self:_wrap_middleware(handler, route.middleware)
    end
    
    self.router:add(methods, route.path, handler)
end

--- 中间件包装器
function _M:_wrap_middleware(handler, middlewares)
    return function(params)
        -- 倒序执行中间件
        for i = #middlewares, 1, -1 do
            local mw = require("think.middleware."..middlewares[i])
            local result = mw.before(params)
            if not result then return end
        end
        
        -- 执行控制器方法
        local result = handler(params)
        
        -- 正序执行后置中间件
        for _, mw_name in ipairs(middlewares) do
            local mw = require("think.middleware."..mw_name)
            mw.after(result)
        end
        
        return result
    end
end

--- 处理HTTP请求
function _M:handle_request()
    -- 初始化请求上下文
    local ctx = {
        uri = ngx.var.request_uri:gsub("?.*", ""),
        method = ngx.req.get_method(),
        params = self:_parse_request_params()
    }
    
    -- 路由匹配
    local handler, route_params = self.router:match(ctx.uri, ctx.method)
    if not handler then
        return self:_response(404, { error = "Route Not Found" })
    end
    
    -- 合并参数
    ctx.params = self:_merge_params(ctx.params, route_params)
    
    -- 执行处理逻辑
    local ok, result = xpcall(handler, debug.traceback, ctx)
    if not ok then
        ngx.log(ngx.ERR, "请求处理失败: ", result)
        return self:_response(500, { error = "Internal Server Error" })
    end
    
    return result
end

--- 解析请求参数
function _M:_parse_request_params()
    local params = {}
    
    -- GET参数
    params.get = ngx.req.get_uri_args()
    
    -- POST参数
    ngx.req.read_body()
    local content_type = ngx.req.get_headers()["Content-Type"]
    if content_type and content_type:find("application/json") then
        params.post = cjson.decode(ngx.req.get_body_data() or "{}")
    else
        params.post = ngx.req.get_post_args()
    end
    
    return params
end

--- 合并路由参数
function _M:_merge_params(base_params, route_params)
    return setmetatable(route_params or {}, { __index = base_params })
end

--- 统一响应处理
function _M:_response(status, data)
    ngx.status = status
    ngx.header["Content-Type"] = "application/json; charset=utf-8"
    ngx.say(cjson.encode(data))
    ngx.exit(status)
end

return _M